home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / util / boot / snap_v2_0.lha / Snap / Snap.c < prev    next >
C/C++ Source or Header  |  1995-09-13  |  34KB  |  1,631 lines

  1. /*
  2.  *    $VER:Snap.c - (10.09.95) 12:15:52 Copyright ⌐ 1995 by Mikael Karlsson & Sylvain ROUGIER
  3.  *
  4.  *      Created: 1988
  5.  *      Modified:    10 Sep 1995    12:15:52
  6.  *
  7.  *      Make>> smake
  8.  *
  9.  * 04/06/95:
  10.  *        Try to compile originale Snap 1.61 src
  11.  *    Bumped to 1.99
  12.  * 04/06/95:
  13.  *        Bumped to 2.00
  14.  *        try to fix bug occuring when cliping gfx on >6 depth screen
  15.  *    10/09/95:
  16.  *        the SwapColor seem not work under CyberGFX V40.?, this is not true, it seems to be a bug of CyberGFX.
  17.  */
  18.  
  19. /***********************************************\
  20. *                                               *
  21. *                     Snap                      *
  22. *         ⌐ Mikael Karlsson 1988-1991           *
  23. *                                               *
  24. \***********************************************/
  25. /* Auto: make "CCEXTRA=-wq -qf"
  26.  */
  27.  
  28. #include <stdio.h>
  29.  
  30. #include "Snap.h"
  31.  
  32. #include "proto/Misc.h"
  33. #include "proto/GfxSnap.h"
  34.  
  35. #ifdef SNAPREXX
  36. #include "minrexx.h"
  37. #include "proto/MinRexx.h"
  38. #endif    /* SNAPREXX */
  39.  
  40. #define ARGVAL( ) ( ( *argv && *++( *argv)) || ( --argc && *++argv))
  41.  
  42. char Version[ ] = "$VER: 2.00 ⌐ 1991 Mikael Karlsson,Absolut Software & Sylvain ROUGIER\n";
  43.  
  44. BOOL Kick36;
  45.  
  46. /* signals */
  47. LONGBITS startsignal, insertsignal, cancelsignal;
  48. LONGBITS donesignal, movesignal, clicksignal;
  49. LONGBITS timersignal, initsignal, cwsignal, ticksignal;
  50. ULONG startsignum = -1L;
  51. ULONG insertsignum = -1L;
  52. ULONG cancelsignum = -1L;
  53. ULONG donesignum = -1L;
  54. ULONG movesignum = -1L;
  55. ULONG clicksignum = -1L;
  56. ULONG initsignum = -1L;
  57. ULONG cwsignum = -1L;
  58. ULONG ticksignum = -1L;
  59. ULONG WaitSignal;
  60.  
  61. /* program */
  62. struct SnapRsrc *SnapRsrc = NULL;
  63. struct Task *MyTask;
  64.  
  65. /* Snap state machine */
  66. WORD action;
  67. WORD state;
  68.  
  69. /* clipboard */
  70. struct IOClipReq *ClipReq = NULL;
  71. struct MsgPort *ClipPort = NULL;
  72.  
  73. /* timer device */
  74. struct MsgPort *TimerPort = NULL;
  75. struct timerequest MyTR;
  76.  
  77. /* input device */
  78. struct MsgPort *inputDevPort = NULL;
  79. struct Interrupt handlerStuff;
  80. struct IOStdReq *inputRequestBlock = NULL;
  81. struct InputEvent SimEvent;
  82. WORD textqual;
  83. WORD gfxqual;
  84. WORD insertkey;
  85. WORD cwkey;
  86. WORD modinsert;
  87.  
  88. UBYTE *CharData = NULL;
  89. UBYTE TrueUnderscore;
  90.  
  91. /* console */
  92. struct MsgPort *ConPort = NULL;
  93. struct IOStdReq *ConIOR = NULL;
  94. struct KeyMap keymap;
  95.  
  96. /* windows */
  97. #ifdef SNAPGFX
  98. struct MsgPort *Sharedport = NULL;
  99. SHORT Sharedrefs;
  100. IMPORT struct Window *ControlWindow;
  101. struct Window *SaveWin = NULL;
  102. IMPORT struct Gadget SaveGad;
  103. IMPORT struct Gadget NameGad;
  104. IMPORT struct StringInfo TranspSI;
  105. IMPORT struct Image ActiveDiskImage;
  106. IMPORT struct Image InactiveDiskImage;
  107. IMPORT struct Image ActiveClipImage;
  108. IMPORT struct Image InactiveClipImage;
  109.  
  110. #endif    /* SNAPGFX */
  111. IMPORT UBYTE *WindowTitle;
  112.  
  113. /* libraries */
  114. IMPORT struct ExecBase *SysBase;
  115. struct IntuitionBase *IntuitionBase = NULL;
  116. struct GfxBase *GfxBase = NULL;
  117. struct Library *LayersBase = NULL;
  118. struct Library *DiskfontBase = NULL;
  119. struct Library *IconBase = NULL;
  120.  
  121. #ifdef SNAPGFX
  122. #ifdef REQLIB
  123. struct ReqBase *ReqBase = NULL;
  124.  
  125. #endif    /* REQLIB */
  126. #ifdef ASLLIB
  127. struct Library *AslBase = NULL;
  128.  
  129. #endif    /* ASLLIB */
  130. #endif    /* SNAPGFX */
  131.  
  132. /* graphics */
  133. struct Screen *theScreen;
  134. struct RastPort rp, TempRp, MyRP;
  135. struct BitMap TempBM, MyBM;
  136. UBYTE *TempRaster = NULL;
  137.  
  138. #ifdef SNAPGFX
  139. #ifdef REQLIB
  140. struct ReqFileRequester *NameFR = NULL;
  141.  
  142. #endif    /* REQLIB */
  143. #ifdef ASLLIB
  144. struct FileRequester *AslNameFR = NULL;
  145.  
  146. #endif    /* ASLLIB */
  147. char SaveName[ DSIZE + FCHARS + 2];
  148. BPTR SnapFile;
  149.  
  150. #endif    /* SNAPGFX */
  151.  
  152. /* ARexx stuff */
  153. #ifdef SNAPREXX
  154. ULONG rexxsignal;
  155. IMPORT struct rexxCommandList rcl[ ];
  156. //WORD disp( );
  157.  
  158. #endif    /* SNAPREXX */
  159.  
  160. #ifdef AZTEC_C
  161. int stricmp( char *s1, char *s2)
  162. {
  163.     char c1, c2;
  164.  
  165.     while ( *s1 && *s2)
  166.     {
  167.         if ( ( c1 = *( s1++)) >= 'a' && c1 <= 'z')
  168.         {
  169.             c1 -= 32;
  170.         }
  171.         if ( ( c2 = *( s2++)) >= 'a' && c2 <= 'z')
  172.         {
  173.             c2 -= 32;
  174.         }
  175.  
  176.         if ( c1 != c2)
  177.         {
  178.             return ( c1 - c2);
  179.         }
  180.     }
  181.  
  182.     return ( *s1 - *s2);
  183. }
  184.  
  185.  
  186. int strnicmp( char *s1, char *s2, int n)
  187. {
  188.     char c1, c2;
  189.  
  190.     while ( *s1 && *s2 && --n > 0)
  191.     {
  192.         c1 = *( s1++);
  193.         c2 = *( s2++);
  194.  
  195.         if ( c1 >= 'a' && c1 <= 'z')
  196.         {
  197.             c1 -= 32;
  198.         }
  199.         if ( c2 >= 'a' && c2 <= 'z')
  200.         {
  201.             c2 -= 32;
  202.         }
  203.  
  204.         if ( c1 != c2)
  205.         {
  206.             return ( c1 - c2);
  207.         }
  208.     }
  209.  
  210.     c1 = *s1;
  211.     c2 = *s2;
  212.  
  213.     if ( c1 >= 'a' && c1 <= 'z')
  214.     {
  215.         c1 -= 32;
  216.     }
  217.     if ( c2 >= 'a' && c2 <= 'z')
  218.     {
  219.         c2 -= 32;
  220.     }
  221.  
  222.     return ( c1 - c2);
  223. }
  224. #endif
  225.  
  226. LONG dectoint( REGISTER char *str)
  227. {
  228.     REGISTER long val = 0;
  229.     REGISTER char c;
  230.  
  231.     while ( ( c = *str) >= '0' && c <= '9')
  232.     {
  233.         val = ( ( ( val << 2) + val) << 1) + c - '0';
  234.         str++;
  235.     }
  236.     return ( val);
  237. }
  238.  
  239. LONG HexToInt(  char *str)
  240. {
  241.     REGISTER long val = 0;
  242.     REGISTER char c;
  243.  
  244.     if ( !strnicmp( str, "0x", 2))
  245.     {
  246.         str += 2;
  247.     }
  248.     while ( c = *str)
  249.     {
  250.         val <<= 4;
  251.         val |= ( c & 15) + ( ( c >= '0' && c <= '9') ? 0 : 9);
  252.         str++;
  253.     }
  254.     return val;
  255. }
  256.  
  257. WORD insertcount;
  258.  
  259. VOID InsertAscii( ULONG ascii)
  260. {
  261.     if ( insertcount == 1)
  262.     {            /* Time for second char */
  263.         /* Not necessary to patch here but it guarantees
  264.            that all inserted chars end up in the same window. */
  265.         SafePatch( );
  266.     }
  267.     if ( AsciiToInputEvent( ascii, &SimEvent, &keymap))
  268.     {
  269.         DoIO( ( struct IORequest *)inputRequestBlock);
  270.         if ( SnapRsrc->chardelay)
  271.         {
  272.             MyTR.tr_node.io_Command = TR_ADDREQUEST;
  273.             MyTR.tr_time.tv_micro = SnapRsrc->chardelay;
  274.             MyTR.tr_time.tv_secs = 0;
  275.             DoIO( ( struct IORequest *)&MyTR);
  276.         }
  277.     }
  278.     ++insertcount;
  279. }
  280.  
  281. #ifdef SNAPGFX
  282. VOID GadText( struct Gadget *Gad, char *Str, LONG Len)
  283. {
  284.     char temp[ 256];
  285.     SHORT i;
  286.  
  287.     SetDrMd( ControlWindow->RPort, JAM2);
  288.     SetAPen( ControlWindow->RPort, 0L);
  289.     RectFill( ControlWindow->RPort, ( LONG) Gad->LeftEdge, ( LONG) Gad->TopEdge,
  290.          ( LONG) Gad->LeftEdge + Gad->Width - 1, ( LONG) Gad->TopEdge + Gad->Height - 1);
  291.     SetAPen( ControlWindow->RPort, 1L);
  292.     SetBPen( ControlWindow->RPort, 0L);
  293.     Move( ControlWindow->RPort,
  294.          ( LONG) Gad->LeftEdge + 1,
  295.      ( LONG) Gad->TopEdge + ControlWindow->RPort->Font->tf_Baseline + 1);
  296.     if ( TextLength( ControlWindow->RPort, Str, Len) > Gad->Width)
  297.     {
  298.         i = Len;
  299.         strncpy( temp, Str, i - 3);
  300.         strcat( temp, "...");
  301.         while ( TextLength( ControlWindow->RPort, temp, ( LONG) i) > Gad->Width)
  302.         {
  303.             --i;
  304.             temp[ i] = '\0';
  305.             temp[ i - 3] = '.';
  306.         }
  307.         Text( ControlWindow->RPort, temp, ( LONG) i);
  308.     }
  309.     else
  310.     {
  311.         Text( ControlWindow->RPort, Str, Len);
  312.     }
  313. }
  314.  
  315.  
  316. VOID SwapColorMap( struct GfxSnap *GS)
  317. {
  318.     struct ViewPort *vp = &GS->window->WScreen->ViewPort;
  319.     LONG i = ( GS->viewmode & HAM ? 16 : 1L << GS->depth);
  320.     ULONG col;
  321.  
  322.     if ( SysBase->LibNode.lib_Version < 39)
  323.     {
  324.         while ( i-- && ( col = GetRGB4( vp->ColorMap, i)) != -1L)
  325.         {
  326.             SetRGB4( vp, i,
  327.                 ( LONG) GS->rgb[ i][ 0] >> 4,
  328.                 ( LONG) GS->rgb[ i][ 1] >> 4,
  329.                 ( LONG) GS->rgb[ i][ 2] >> 4);
  330.             GS->rgb[ i][ 0] = RGB4ToRR( col);
  331.             GS->rgb[ i][ 1] = RGB4ToGG( col);
  332.             GS->rgb[ i][ 2] = RGB4ToBB( col);
  333.         }
  334.     }
  335.     else
  336.     {
  337.         while ( i--)
  338.         {
  339.             ULONG RGB[ 3];
  340.  
  341.             GetRGB32( vp->ColorMap, i, 1, RGB);
  342.             SetRGB32CM( vp->ColorMap, i, RGB8ToRGB32( GS->rgb[ i][ 0]), RGB8ToRGB32( GS->rgb[ i][ 1]), RGB8ToRGB32( GS->rgb[ i][ 2]));
  343.             GS->rgb[ i][ 0] = RGB32ToRGB8( RGB[ 0]);
  344.             GS->rgb[ i][ 1] = RGB32ToRGB8( RGB[ 1]);
  345.             GS->rgb[ i][ 2] = RGB32ToRGB8( RGB[ 2]);
  346.         }
  347.     }
  348. }
  349.  
  350. VOID CheckWindowMsgs( )
  351. {
  352.     struct IntuiMessage *Msg;
  353.     struct IntuiMessage *QdMsg = NULL;
  354.     ULONG im_Class;
  355.     USHORT Code;
  356.     struct Window *Win;
  357.     struct Gadget *Gad;
  358.     struct GfxSnap *SwapGS = NULL;
  359.  
  360.     while ( Sharedport &&
  361.         ( QdMsg || ( Msg = ( struct IntuiMessage *)GetMsg( Sharedport))))
  362.     {
  363.         if ( QdMsg)
  364.         {
  365.             Msg = QdMsg;
  366.             QdMsg = NULL;
  367.         }
  368.         im_Class = Msg->Class;
  369.         Code = Msg->Code;
  370.         Win = Msg->IDCMPWindow;
  371.         Gad = ( struct Gadget *)Msg->IAddress;
  372.         ReplyMsg( ( struct Message *)Msg);
  373.         switch ( im_Class)
  374.         {
  375.         case CLOSEWINDOW:
  376.             {
  377.                 struct GfxSnap *GS = NULL;
  378.  
  379.                 if ( Win == ControlWindow)
  380.                 {
  381.                     ControlWindow = NULL;
  382.                     if ( SaveWin)
  383.                     {
  384.                         SetWindowTitles( SaveWin, ( char *)WindowTitle, ( char *)-1);
  385.                         SaveWin = NULL;
  386.                     }
  387.                 }
  388.                 else
  389.                 {
  390.                     GS = ( struct GfxSnap *)Win->UserData;
  391.                     Snp_FreeBitMap( GS->BitMap, GS->width, GS->height);
  392.                     GS->BitMap = NULL;
  393.  
  394.                     if ( Win == SaveWin || Sharedrefs == 1)
  395.                     {
  396.                         if ( ControlWindow)
  397.                         {
  398.                             OffGadget( &SaveGad, ControlWindow, NULL);
  399.                         }
  400.                         SaveWin = NULL;
  401.                     }
  402.                 }
  403.                 closesharedwindow( Win);
  404.                 DeleteGfxSnap( GS);
  405.                 break;
  406.             }
  407.         case NEWSIZE:
  408.             {
  409.                 AdjustSize( ( struct GfxSnap *)Win->UserData);
  410.                 break;
  411.             }
  412.         case MOUSEMOVE:
  413.             {
  414.                 /* Collapse all consecutively queued MOUSEMOVE msgs */
  415.                 while ( ( QdMsg = ( struct IntuiMessage *)GetMsg( Sharedport))
  416.                        && ( QdMsg->Class == MOUSEMOVE))
  417.                 {
  418.                     ReplyMsg( ( struct Message *)QdMsg);
  419.                 }
  420.                 SyncGS( ( struct GfxSnap *)Win->UserData);
  421.                 break;
  422.             }
  423.         case REFRESHWINDOW:
  424.             {
  425.                 BeginRefresh( Win);
  426.                 SyncGS( ( struct GfxSnap *)Win->UserData);
  427.                 EndRefresh( Win, 1L);
  428.             }
  429.         case INACTIVEWINDOW:
  430.             {
  431.                 if ( Win != ControlWindow)
  432.                 {
  433.                     struct GfxSnap *GS;
  434.  
  435.                     GS = ( struct GfxSnap *)Win->UserData;
  436.                     if ( SwapGS)
  437.                     {
  438.                         SwapColorMap( SwapGS);
  439.                         SwapGS = NULL;
  440.                     }
  441.                     GS->DiskGad.GadgetRender = ( APTR) & InactiveDiskImage;
  442.                     GS->ClipGad.GadgetRender = ( APTR) & InactiveClipImage;
  443.                     RefreshGList( &GS->DiskGad, GS->window, NULL, -1);
  444.                 }
  445.                 break;
  446.             }
  447.         case ACTIVEWINDOW:
  448.             {
  449.                 if ( Win != ControlWindow)
  450.                 {
  451.                     struct GfxSnap *GS;
  452.  
  453.                     GS = ( struct GfxSnap *)Win->UserData;
  454.                     GS->DiskGad.GadgetRender = ( APTR) & ActiveDiskImage;
  455.                     GS->ClipGad.GadgetRender = ( APTR) & ActiveClipImage;
  456.                     RefreshGList( &GS->DiskGad, GS->window, NULL, -1);
  457.                 }
  458.                 break;
  459.             }
  460.         case GADGETUP:
  461.             {
  462.                 switch ( Gad->GadgetID)
  463.                 {
  464.                 case VPROP:
  465.                 case HPROP:
  466.                     {
  467.                         SyncGS( ( struct GfxSnap *)Win->UserData);
  468.                         break;
  469.                     }
  470.                 case SAVEGAD:
  471.                     {
  472.                           savepic:
  473.                         if ( SaveWin)
  474.                         {
  475.                             WORD success = 0;
  476.                             struct GfxSnap *GS;
  477.  
  478.                             GS = ( struct GfxSnap *)SaveWin->UserData;
  479.  
  480.                             if ( SaveName[ 0] == '\0')
  481.                             {
  482.                                 DisplayBeep( NULL);
  483.                                 ActivateGadget( &NameGad, ControlWindow, NULL);
  484.                                 break;
  485.                             }
  486.                             SnapFile = ( BPTR) Open( ( char *)SaveName, MODE_NEWFILE);
  487.                             if ( SnapFile)
  488.                             {
  489.                                 struct CBFHandle CBFH;
  490.  
  491.                                 CBFH.Type = CBFFILE;
  492.                                 CBFH.Handle.File = SnapFile;
  493.                                 success = SaveGS( GS, &CBFH);
  494.                                 Close( SnapFile);
  495.                             }
  496.                             if ( success)
  497.                             {
  498.                                 SetWindowTitles( ControlWindow, "Saved ok", ( char *)-1);
  499.                             }
  500.                             else
  501.                             {
  502.                                 DeleteFile( ( char *)SaveName);
  503.                                 DisplayBeep( NULL);
  504.                                 SetWindowTitles( ControlWindow, "Save failed", ( char *)-1);
  505.                             }
  506.                         }
  507.                         break;
  508.                     }
  509.                 case NAMEGAD:
  510.                     {    /* Should only happen with Req */
  511. #ifdef ASLLIB
  512.                         if ( ( AslNameFR) && ( Kick36))
  513.                         {
  514.                             if ( RequestFile( AslNameFR))
  515.                             {
  516.                                 strncpy( SaveName, AslNameFR->rf_Dir, sizeof ( SaveName));
  517.                                 AddPart( ( UBYTE *) SaveName,
  518.                                     ( UBYTE *) AslNameFR->rf_File,
  519.                                     sizeof ( SaveName));
  520.                             }
  521.                             GadText( &NameGad, SaveName, ( LONG) strlen( SaveName));
  522.                         }
  523. #else
  524.                         if ( 0)
  525.                         {
  526.                         }
  527. #endif    /* ASLLIB */
  528. #ifdef REQLIB
  529.                         else if ( NameFR)
  530.                         {
  531.                             NameFR->Title = "Save picture as...";
  532.                             NameFR->PathName = SaveName;
  533.                             NameFR->Window = ControlWindow;
  534.                             ( VOID) BruceFileRequester( NameFR);
  535.                             GadText( &NameGad, SaveName, ( LONG) strlen( SaveName));
  536.                         }
  537. #endif    /* REQLIB */
  538.                         break;
  539.                     }
  540.                 case DISKGAD:
  541.                     {
  542.                         struct GfxSnap *GS;
  543.  
  544.                         if ( !ControlWindow && !OpenCW( ))
  545.                         {
  546.                             DisplayBeep( NULL);
  547.                             break;
  548.                         }
  549.                         if ( Win == SaveWin)
  550.                         {
  551.                             goto savepic;
  552.                         }
  553.                         if ( SaveWin)
  554.                         {
  555.                             SetWindowTitles( SaveWin, ( char *)WindowTitle, ( char *)-1);
  556.                             GS = ( struct GfxSnap *)SaveWin->UserData;
  557.                             RefreshGList( &GS->DiskGad, GS->window, NULL, 1L);
  558.                         }
  559.                         else
  560.                         {
  561.                             GadText( &SaveGad, "Save", 4L);
  562.                             OnGadget( &SaveGad, ControlWindow, NULL);
  563.                         }
  564.                         SaveWin = Win;
  565.                         SetWindowTitles( SaveWin, "Selected", ( char *)-1);
  566.                         GS = ( struct GfxSnap *)SaveWin->UserData;
  567.                         RefreshGList( &GS->DiskGad, GS->window, NULL, 1L);
  568.                         break;
  569.                     }
  570.                 case CLIPGAD:
  571.                     {
  572.                         struct CBFHandle CBFH;
  573.                         struct GfxSnap *GS = ( struct GfxSnap *)Win->UserData;
  574.  
  575.                         CBFH.Type = CBFCLIP;
  576.                         CBFH.Handle.ClipReq = ClipReq;
  577.                         if ( !SaveGS( GS, &CBFH))
  578.                         {
  579.                             DisplayBeep( NULL);
  580.                         }
  581.                         break;
  582.                     }
  583.                 default:
  584.                     {
  585.                         break;
  586.                     }
  587.                 }
  588.                 break;
  589.             }
  590.         case MOUSEBUTTONS:
  591.             {
  592.                 if ( Win != ControlWindow)
  593.                 {
  594.                     if ( Code == SELECTDOWN && !SwapGS)
  595.                     {
  596.                         SwapGS = ( struct GfxSnap *)Win->UserData;
  597.                         SwapColorMap( SwapGS);
  598.                     }
  599.                     else if ( Code == SELECTUP && SwapGS)
  600.                     {
  601.                         SwapColorMap( SwapGS);
  602.                         SwapGS = NULL;
  603.                     }
  604.                 }
  605.                 break;
  606.             }
  607.         default:
  608.             {
  609.                 break;
  610.             }
  611.         }
  612.     }
  613.     if ( QdMsg)
  614.     {
  615.         ReplyMsg( ( struct Message *)QdMsg);
  616.     }
  617. }
  618. #endif    /* SNAPGFX */
  619.  
  620. #define SnapWriteStr( str) fputs( str, stdout)
  621. #define SnapWriteChar( char) fputc( char, stdout)
  622.  
  623. struct QualPair
  624. {
  625.     char *str;
  626.     WORD val;
  627. };
  628.  
  629. struct QualPair Qualifiers[ ] =
  630. {
  631.     {"LSHIFT", IEQUALIFIER_LSHIFT},
  632.     {"RSHIFT", IEQUALIFIER_RSHIFT},
  633.     {"CONTROL", IEQUALIFIER_CONTROL},
  634.     {"LALT", IEQUALIFIER_LALT},
  635.     {"RALT", IEQUALIFIER_RALT},
  636.     {"LCOMMAND", IEQUALIFIER_LCOMMAND},
  637.     {"RCOMMAND", IEQUALIFIER_RCOMMAND},
  638.     {"MIDBUTTON", IEQUALIFIER_MIDBUTTON}
  639. };
  640.  
  641. WORD ParseQual( char *quals)
  642. {
  643.     char *temp;
  644.     WORD i;
  645.     char oldc;
  646.     WORD qual = 0;
  647.  
  648.     if ( ( '0' >= *quals) && ( *quals <= '9'))
  649.     {
  650.         return ( WORD)HexToInt(  quals);
  651.     }
  652.  
  653.     while ( *quals)
  654.     {
  655.         temp = quals;
  656.         while ( ( oldc = *quals) && oldc != '+')
  657.         {
  658.             quals++;
  659.         }
  660.         *quals = 0;
  661.         for ( i = 0; i < ( sizeof ( Qualifiers) / sizeof ( Qualifiers[ 0])); i++)
  662.         {
  663.             if ( !stricmp( temp, Qualifiers[ i].str))
  664.             {
  665.                 qual |= Qualifiers[ i].val;
  666.                 break;
  667.             }
  668.         }
  669.         if ( *quals = oldc)
  670.         {
  671.             quals++;
  672.         }
  673.     }
  674.     return qual;
  675. }
  676.  
  677. WORD SetAltFont( char *str)
  678. {
  679.     struct TextAttr ta;
  680.     struct TextFont *NewFont;
  681.     char temp[ 33];
  682.     WORD pos = 0;
  683.  
  684.     if ( strlen( str) <= 32)
  685.     {
  686.  
  687.         strcpy( temp, str);
  688.         ta.ta_Name = ( UBYTE *) temp;
  689.         while ( temp[ pos] != '\0' && temp[ pos] != '/')
  690.         {
  691.             ++pos;
  692.         }
  693.         if ( temp[ pos] == '\0')
  694.         {        /* No size */
  695.             ta.ta_YSize = 8;
  696.         }
  697.         else
  698.         {
  699.             temp[ pos] = '\0';
  700.             ta.ta_YSize = dectoint( &temp[ pos + 1]);
  701.         }
  702.         if ( pos > 5)
  703.         {
  704.             if ( stricmp( &temp[ pos - 5], ".font"))
  705.             {
  706.                 strcpy( &temp[ pos], ".font");
  707.             }
  708.         }
  709.         else
  710.         {
  711.             strcpy( &temp[ pos], ".font");
  712.         }
  713.         ta.ta_Style = 0;
  714.         ta.ta_Flags = 0;
  715.         NewFont = SmartOpenFont( &ta);
  716.         if ( NewFont)
  717.         {
  718.             if ( SnapRsrc->AlternateFont)
  719.             {
  720.                 CacheSync( SnapRsrc->AlternateFont);
  721.                 CloseFont( SnapRsrc->AlternateFont);
  722.             }
  723.             SnapRsrc->AlternateFont = NewFont;
  724.         }
  725.     }
  726.     return ( WORD)( NewFont ? 1 : 0);
  727. }
  728.  
  729. struct SnapRsrc DefaultRsrc =
  730. {
  731.     {NULL, NULL, NT_RESOURCE, 0, SNAPRSRC},        /* Node */
  732.     NULL,            /* Task */
  733.     52,            /* Priority */
  734.     IEQUALIFIER_RCOMMAND,    /* Graphics qualifier */
  735.     IEQUALIFIER_LCOMMAND,    /* Text qualifier */
  736.     0x17,            /* Insert key */
  737.     0x11,            /* Control Window key */
  738.     {'>', ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},    /* Prepend */
  739.     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},    /* Append */
  740.     TRUEUNDERSCORE,        /* Flags */
  741.     0,            /* Char delay */
  742.     0,            /* Line delay */
  743.     0x7777,            /* Crawl pattern */
  744.     UNIT_FRAME,        /* Starting unit */
  745.     1,            /* Frame mask */
  746.     '?',            /* Bad char */
  747.     10,            /* Cache size */
  748.     1,            /* Extra line spacing */
  749.     {NULL, NULL, NULL},    /* MinList, Cached windows */
  750.     NULL            /* Alternate font */
  751. };
  752.  
  753. #ifdef LATTICE
  754. VOID main( int argc, char **argv)
  755. #else
  756. WORD main( int argc, char **argv)
  757. #endif
  758. {
  759.     WORD create = 0, usage = 0;
  760.  
  761. #ifdef AZTEC_C
  762.     Enable_Abort = 0;
  763. #endif    /* AZTEC_C */
  764.  
  765.     Kick36 = ( SysBase->LibNode.lib_Version >= 36 ? 1 : 0);
  766.  
  767.     if ( !( SnapRsrc = ( struct SnapRsrc *)OpenResource( SNAPRSRC)))
  768.     {
  769.         create = 1;
  770.         SnapRsrc = Create( SnapRsrc);
  771.         CopyMem( ( char *)&DefaultRsrc, ( char *)SnapRsrc, sizeof ( struct SnapRsrc));
  772.  
  773.         SnapRsrc->Task = FindTask( NULL);
  774.         NewList( ( struct List *)&SnapRsrc->CachedWindows);
  775.         AddResource( ( struct MiscResource *)SnapRsrc);
  776.     }
  777.  
  778.     /* Open libraries since we might need them when parsing arguments */
  779.     if ( !OpenLibs( ))
  780.     {
  781.         goto exitpoint;
  782.     }
  783.  
  784.     if ( !argc)
  785.     {            /* WB Startup */
  786.         if ( !create)
  787.         {        /* Second time from WB -- Remove Snap */
  788.             Signal( SnapRsrc->Task, SIGBREAKF_CTRL_C);
  789.             goto exitpoint;
  790.         }
  791.         else if ( IconBase)
  792.         {        /* Is it possible to be started from Workbench
  793.                    without icon.library being available. */
  794.             BPTR olddir;
  795.             struct WBStartup *wbstartup;
  796.             struct DiskObject *diskobject;
  797.             char *val;
  798.  
  799.             wbstartup = ( struct WBStartup *)argv;
  800.             olddir = CurrentDir( wbstartup->sm_ArgList[ 0].wa_Lock);
  801.             diskobject = GetDiskObject( wbstartup->sm_ArgList[ 0].wa_Name);
  802.             if ( !diskobject)
  803.             {
  804.                 goto skipargs;
  805.             }
  806.             if ( val = FindToolType( diskobject->do_ToolTypes, "PRIORITY"))
  807.             {
  808.                 WORD pri = dectoint( val);
  809.  
  810.                 if ( pri > 50 && pri < 128)
  811.                 {
  812.                     SnapRsrc->Priority = pri;
  813.                 }
  814.             }
  815.             if ( val = FindToolType( diskobject->do_ToolTypes, "TEXTQUAL"))
  816.             {
  817.                 if ( !( SnapRsrc->textqual = ParseQual( val)))
  818.                 {
  819.                     SnapRsrc->textqual = IEQUALIFIER_LCOMMAND;
  820.                 }
  821.             }
  822.             if ( val = FindToolType( diskobject->do_ToolTypes, "GFXQUAL"))
  823.             {
  824.                 if ( !( SnapRsrc->gfxqual = ParseQual( val)))
  825.                 {
  826.                     SnapRsrc->gfxqual = IEQUALIFIER_RCOMMAND;
  827.                 }
  828.             }
  829.             if ( val = FindToolType( diskobject->do_ToolTypes, "INSERTKEY"))
  830.             {
  831.                 SnapRsrc->insertkey = HexToInt( val);
  832.             }
  833.             if ( val = FindToolType( diskobject->do_ToolTypes, "CWKEY"))
  834.             {
  835.                 SnapRsrc->cwkey = HexToInt( val);
  836.             }
  837.             if ( val = FindToolType( diskobject->do_ToolTypes, "APPEND"))
  838.             {
  839.                 strncpy( &SnapRsrc->Append[ 0], val, 16);
  840.             }
  841.             if ( val = FindToolType( diskobject->do_ToolTypes, "PREPEND"))
  842.             {
  843.                 strncpy( &SnapRsrc->Prepend[ 0], val, 16);
  844.             }
  845.             if ( val = FindToolType( diskobject->do_ToolTypes, "CHARDELAY"))
  846.             {
  847.                 SnapRsrc->chardelay = dectoint( val);
  848.             }
  849.             if ( val = FindToolType( diskobject->do_ToolTypes, "LINEDELAY"))
  850.             {
  851.                 SnapRsrc->linedelay = dectoint( val) * 1000;
  852.             }
  853.             if ( val = FindToolType( diskobject->do_ToolTypes, "CRAWLPTRN"))
  854.             {
  855.                 SnapRsrc->CrawlPtrn = HexToInt( val);
  856.             }
  857.             if ( val = FindToolType( diskobject->do_ToolTypes, "XEROX"))
  858.             {
  859.                 SnapRsrc->flags |= XEROX;
  860.             }
  861.             if ( val = FindToolType( diskobject->do_ToolTypes, "NOXEROX"))
  862.             {
  863.                 SnapRsrc->flags &= ~XEROX;
  864.             }
  865.             if ( val = FindToolType( diskobject->do_ToolTypes, "EARLYPATCH"))
  866.             {
  867.                 SnapRsrc->flags |= EARLYPATCH;
  868.             }
  869.             if ( val = FindToolType( diskobject->do_ToolTypes, "NOEARLYPATCH"))
  870.             {
  871.                 SnapRsrc->flags &= ~EARLYPATCH;
  872.             }
  873.             if ( val = FindToolType( diskobject->do_ToolTypes, "STARTUNIT"))
  874.             {
  875.                 if ( *val == '1')
  876.                 {
  877.                     SnapRsrc->StartUnit = UNIT_CHAR;
  878.                 }
  879.                 else
  880.                 {
  881.                     SnapRsrc->StartUnit = UNIT_FRAME;
  882.                 }
  883.             }
  884.             if ( val = FindToolType( diskobject->do_ToolTypes, "TRUEUNDERSCORE"))
  885.             {
  886.                 SnapRsrc->flags |= TRUEUNDERSCORE;
  887.             }
  888.             if ( val = FindToolType( diskobject->do_ToolTypes, "FAKEUNDERSCORE"))
  889.             {
  890.                 SnapRsrc->flags &= ~TRUEUNDERSCORE;
  891.             }
  892.             if ( val = FindToolType( diskobject->do_ToolTypes, "JOINLONG"))
  893.             {
  894.                 SnapRsrc->flags |= JOINLONG;
  895.             }
  896.             if ( val = FindToolType( diskobject->do_ToolTypes, "NOJOINLONG"))
  897.             {
  898.                 SnapRsrc->flags &= ~JOINLONG;
  899.             }
  900.             if ( val = FindToolType( diskobject->do_ToolTypes, "SIMPLEREFRESH"))
  901.             {
  902.                 SnapRsrc->flags |= SIMPLEREFRESH;
  903.             }
  904.             if ( val = FindToolType( diskobject->do_ToolTypes, "SMARTREFRESH"))
  905.             {
  906.                 SnapRsrc->flags &= ~SIMPLEREFRESH;
  907.             }
  908.             if ( val = FindToolType( diskobject->do_ToolTypes, "PLANEMASK"))
  909.             {
  910.                 SnapRsrc->FrameMask = HexToInt( val);
  911.             }
  912.             if ( val = FindToolType( diskobject->do_ToolTypes, "CACHESIZE"))
  913.             {
  914.                 SnapRsrc->CacheSize = dectoint( val);
  915.             }
  916.             if ( val = FindToolType( diskobject->do_ToolTypes, "LEADING"))
  917.             {
  918.                 SnapRsrc->Leading = dectoint( val);
  919.             }
  920.             if ( val = FindToolType( diskobject->do_ToolTypes, "BADCHAR"))
  921.             {
  922.                 SnapRsrc->BadChar = ( *val ? *val : 0);
  923.             }
  924.             if ( val = FindToolType( diskobject->do_ToolTypes, "ALTFONT"))
  925.             {
  926.                 SetAltFont( val);
  927.             }
  928.             FreeDiskObject( diskobject);
  929.             goto skipargs;
  930.         }
  931.     }
  932.  
  933.     if ( create)
  934.     {
  935.         SnapWriteStr( "Snap");
  936.         SnapWriteStr( &Version[ 5]);
  937.     }
  938.  
  939.     for ( argc--, argv++; argc > 0; argc--, argv++)
  940.     {
  941.         if ( **argv == '-')
  942.         {        /* Argument coming up */
  943.             switch ( *++( *argv))
  944.             {
  945.             case 'p':
  946.                   priority:{
  947.                     /* Priority */
  948.                     if ( ARGVAL( ))
  949.                     {
  950.                         WORD pri = dectoint( *argv);
  951.  
  952.                         if ( pri > 50 && pri < 128)
  953.                         {
  954.                             SnapRsrc->Priority = pri;
  955.                         }
  956.                     }
  957.                     else
  958.                     {
  959.                         usage = 1;
  960.                     }
  961.                     break;
  962.                 }
  963.             case 't':
  964.                   textqual:{
  965.                     if ( ARGVAL( ))
  966.                     {
  967.                         if ( !( SnapRsrc->textqual = ParseQual( *argv)))
  968.                         {
  969.                             SnapRsrc->textqual = IEQUALIFIER_LCOMMAND;
  970.                         }
  971.                     }
  972.                     else
  973.                     {
  974.                         usage = 1;
  975.                     }
  976.                     break;
  977.                 }
  978. #ifdef SNAPGFX
  979.             case 'g':
  980.                   gfxqual:{
  981.                     if ( ARGVAL( ))
  982.                     {
  983.                         if ( !( SnapRsrc->gfxqual = ParseQual( *argv)))
  984.                         {
  985.                             SnapRsrc->gfxqual = IEQUALIFIER_RCOMMAND;
  986.                         }
  987.                     }
  988.                     else
  989.                     {
  990.                         usage = 1;
  991.                     }
  992.                     break;
  993.                 }
  994. #endif    /* SNAPGFX */
  995.             case 'i':
  996.                   insertkey:{
  997.                     if ( ARGVAL( ))
  998.                     {
  999.                         SnapRsrc->insertkey = HexToInt( *argv);
  1000.                     }
  1001.                     else
  1002.                     {
  1003.                         usage = 1;
  1004.                     }
  1005.                     break;
  1006.                 }
  1007. #ifdef SNAPGFX
  1008.             case 'w':
  1009.                   cwkey:{
  1010.                     if ( ARGVAL( ))
  1011.                     {
  1012.                         SnapRsrc->cwkey = HexToInt( *argv);
  1013.                     }
  1014.                     else
  1015.                     {
  1016.                         usage = 1;
  1017.                     }
  1018.                     break;
  1019.                 }
  1020. #endif    /* SNAPGFX */
  1021.             case 'c':
  1022.                   chardelay:{
  1023.                     if ( ARGVAL( ))
  1024.                     {
  1025.                         SnapRsrc->chardelay = dectoint( *argv) * 1000;
  1026.                     }
  1027.                     else
  1028.                     {
  1029.                         usage = 1;
  1030.                     }
  1031.                     break;
  1032.                 }
  1033.             case 'l':
  1034.                   linedelay:{
  1035.                     if ( ARGVAL( ))
  1036.                     {
  1037.                         SnapRsrc->linedelay = dectoint( *argv) * 1000;
  1038.                     }
  1039.                     else
  1040.                     {
  1041.                         usage = 1;
  1042.                     }
  1043.                     break;
  1044.                 }
  1045.             case 'a':
  1046.                   crawlptrn:{
  1047.                     if ( ARGVAL( ))
  1048.                     {
  1049.                         SnapRsrc->CrawlPtrn = HexToInt( *argv);
  1050.                     }
  1051.                     else
  1052.                     {
  1053.                         usage = 1;
  1054.                     }
  1055.                     break;
  1056.                 }
  1057.             case 'X':
  1058.                   noxerox:{
  1059.                     SnapRsrc->flags &= ~XEROX;
  1060.                     break;
  1061.                 }
  1062.             case 'x':
  1063.                   xerox:{
  1064.                     SnapRsrc->flags |= XEROX;
  1065.                     break;
  1066.                 }
  1067.             case 'E':
  1068.                   noearlypatch:{
  1069.                     SnapRsrc->flags &= ~EARLYPATCH;
  1070.                     break;
  1071.                 }
  1072.             case 'e':
  1073.                   earlypatch:{
  1074.                     SnapRsrc->flags |= EARLYPATCH;
  1075.                     break;
  1076.                 }
  1077.             case 'R':
  1078.                   fakeunderscore:{
  1079.                     SnapRsrc->flags &= ~TRUEUNDERSCORE;
  1080.                     break;
  1081.                 }
  1082.             case 'r':
  1083.                   realunderscore:{
  1084.                     SnapRsrc->flags |= TRUEUNDERSCORE;
  1085.                     break;
  1086.                 }
  1087.             case 'J':
  1088.                   nojoinlong:{
  1089.                     SnapRsrc->flags &= ~JOINLONG;
  1090.                     break;
  1091.                 }
  1092.             case 'j':
  1093.                   joinlong:{
  1094.                     SnapRsrc->flags |= JOINLONG;
  1095.                     break;
  1096.                 }
  1097.             case 'A':
  1098.                   append:{
  1099.                     char *dest = &SnapRsrc->Append[ 0];
  1100.  
  1101.                     if ( ( *argv && *++( *argv)) || ( --argc && ++argv))
  1102.                     {    /* "" is ok */
  1103.                         char *src = *argv;
  1104.                         WORD i = 16;
  1105.  
  1106.                         while ( *src && i--)
  1107.                         {
  1108.                             *dest++ = *src++;
  1109.                         }
  1110.                         *dest = '\0';
  1111.                     }
  1112.                     else
  1113.                     {
  1114.                         usage = 1;
  1115.                     }
  1116.                     break;
  1117.                 }
  1118.             case 'P':
  1119.                   prepend:{
  1120.                     char *dest = &SnapRsrc->Prepend[ 0];
  1121.  
  1122.                     if ( ( *argv && *++( *argv)) || ( --argc && ++argv))
  1123.                     {    /* "" is ok */
  1124.                         char *src = *argv;
  1125.                         WORD i = 16;
  1126.  
  1127.                         while ( *src && i--)
  1128.                         {
  1129.                             *dest++ = *src++;
  1130.                         }
  1131.                         *dest = '\0';
  1132.                     }
  1133.                     else
  1134.                     {
  1135.                         usage = 1;
  1136.                     }
  1137.                     break;
  1138.                 }
  1139.             case 'u':
  1140.                   startunit:{
  1141.                     if ( ARGVAL( ))
  1142.                     {
  1143.                         if ( **argv == '1')
  1144.                         {
  1145.                             SnapRsrc->StartUnit = UNIT_CHAR;
  1146.                         }
  1147.                         else
  1148.                         {
  1149.                             SnapRsrc->StartUnit = UNIT_FRAME;
  1150.                         }
  1151.                     }
  1152.                     else
  1153.                     {
  1154.                         usage = 1;
  1155.                     }
  1156.                     break;
  1157.                 }
  1158.             case 'b':
  1159.                   planemask:{
  1160.                     if ( ARGVAL( ))
  1161.                     {
  1162.                         SnapRsrc->FrameMask = HexToInt( *argv);
  1163.                     }
  1164.                     else
  1165.                     {
  1166.                         usage = 1;
  1167.                     }
  1168.                     break;
  1169.                 }
  1170. #ifdef SNAPGFX
  1171.             case 's':
  1172.                   smartrefresh:{
  1173.                     SnapRsrc->flags &= ~SIMPLEREFRESH;
  1174.                     break;
  1175.                 }
  1176.             case 'S':
  1177.                   simplerefresh:{
  1178.                     SnapRsrc->flags |= SIMPLEREFRESH;
  1179.                     break;
  1180.                 }
  1181. #endif    /* SNAPGFX */
  1182.             case 'C':
  1183.                   cachesize:{
  1184.                     if ( ARGVAL( ))
  1185.                     {
  1186.                         SnapRsrc->CacheSize = dectoint( *argv);
  1187.                     }
  1188.                     else
  1189.                     {
  1190.                         usage = 1;
  1191.                     }
  1192.                     break;
  1193.                 }
  1194.             case 'L':
  1195.                   leading:{
  1196.                     if ( ARGVAL( ))
  1197.                     {
  1198.                         SnapRsrc->Leading = dectoint( *argv);
  1199.                     }
  1200.                     else
  1201.                     {
  1202.                         usage = 1;
  1203.                     }
  1204.                     break;
  1205.                 }
  1206.             case 'B':
  1207.                   badchar:{
  1208.                     if ( ARGVAL( ))
  1209.                     {
  1210.                         SnapRsrc->BadChar = dectoint( *argv);
  1211.                     }
  1212.                     else
  1213.                     {
  1214.                         usage = 1;
  1215.                     }
  1216.                     break;
  1217.                 }
  1218.             case 'F':
  1219.                   altfont:{
  1220.                     if ( ARGVAL( ))
  1221.                     {
  1222.                         SetAltFont( *argv);
  1223.                     }
  1224.                     else
  1225.                     {
  1226.                         usage = 1;
  1227.                     }
  1228.                     break;
  1229.                 }
  1230.             case 'Q':
  1231.             case 'q':
  1232.                   quit:{
  1233.                     if ( create)
  1234.                     {
  1235.                         goto close;
  1236.                     }
  1237.                     else
  1238.                     {
  1239.                         Signal( SnapRsrc->Task, SIGBREAKF_CTRL_C);
  1240.                         goto exitpoint;
  1241.                     }
  1242.                 }
  1243.             case '?':
  1244.                 {
  1245.                     usage = 1;
  1246.                     break;
  1247.                 }
  1248.             default:
  1249.                 {
  1250.                     SnapWriteStr( "Bad option: -");
  1251.                     SnapWriteChar( ( int)**argv);
  1252.                     SnapWriteStr( ".\n");
  1253.                     usage = 1;
  1254.                     break;
  1255.                 }
  1256.             }
  1257.         }
  1258.         else
  1259.         {
  1260. #ifdef SNAPGFX
  1261.             char *keyword = *argv;
  1262.  
  1263.             *argv = NULL;
  1264.             if ( !stricmp( keyword, "PRIORITY"))
  1265.             {
  1266.                 goto priority;    /* Terrible, ain't it? */
  1267.             }
  1268.             else if ( !stricmp( keyword, "TEXTQUAL"))
  1269.             {
  1270.                 goto textqual;
  1271.             }
  1272.             else if ( !stricmp( keyword, "GFXQUAL"))
  1273.             {
  1274.                 goto gfxqual;
  1275.             }
  1276.             else if ( !stricmp( keyword, "INSERTKEY"))
  1277.             {
  1278.                 goto insertkey;
  1279.             }
  1280.             else if ( !stricmp( keyword, "CWKEY"))
  1281.             {
  1282.                 goto cwkey;
  1283.             }
  1284.             else if ( !stricmp( keyword, "PREPEND"))
  1285.             {
  1286.                 goto prepend;
  1287.             }
  1288.             else if ( !stricmp( keyword, "APPEND"))
  1289.             {
  1290.                 goto append;
  1291.             }
  1292.             else if ( !stricmp( keyword, "CHARDELAY"))
  1293.             {
  1294.                 goto chardelay;
  1295.             }
  1296.             else if ( !stricmp( keyword, "LINEDELAY"))
  1297.             {
  1298.                 goto linedelay;
  1299.             }
  1300.             else if ( !stricmp( keyword, "CRAWLPTRN"))
  1301.             {
  1302.                 goto crawlptrn;
  1303.             }
  1304.             else if ( !stricmp( keyword, "XEROX"))
  1305.             {
  1306.                 goto xerox;
  1307.             }
  1308.             else if ( !stricmp( keyword, "NOXEROX"))
  1309.             {
  1310.                 goto noxerox;
  1311.             }
  1312.             else if ( !stricmp( keyword, "EARLYPATCH"))
  1313.             {
  1314.                 goto earlypatch;
  1315.             }
  1316.             else if ( !stricmp( keyword, "NOEARLYPATCH"))
  1317.             {
  1318.                 goto noearlypatch;
  1319.             }
  1320.             else if ( !stricmp( keyword, "TRUEUNDERSCORE"))
  1321.             {
  1322.                 goto realunderscore;
  1323.             }
  1324.             else if ( !stricmp( keyword, "FAKEUNDERSCORE"))
  1325.             {
  1326.                 goto fakeunderscore;
  1327.             }
  1328.             else if ( !stricmp( keyword, "JOINLONG"))
  1329.             {
  1330.                 goto joinlong;
  1331.             }
  1332.             else if ( !stricmp( keyword, "NOJOINLONG"))
  1333.             {
  1334.                 goto nojoinlong;
  1335.             }
  1336.             else if ( !stricmp( keyword, "SIMPLEREFRESH"))
  1337.             {
  1338.                 goto simplerefresh;
  1339.             }
  1340.             else if ( !stricmp( keyword, "SMARTREFRESH"))
  1341.             {
  1342.                 goto smartrefresh;
  1343.             }
  1344.             else if ( !stricmp( keyword, "STARTUNIT"))
  1345.             {
  1346.                 goto startunit;
  1347.             }
  1348.             else if ( !stricmp( keyword, "PLANEMASK"))
  1349.             {
  1350.                 goto planemask;
  1351.             }
  1352.             else if ( !stricmp( keyword, "CACHESIZE"))
  1353.             {
  1354.                 goto cachesize;
  1355.             }
  1356.             else if ( !stricmp( keyword, "LEADING"))
  1357.             {
  1358.                 goto leading;
  1359.             }
  1360.             else if ( !stricmp( keyword, "BADCHAR"))
  1361.             {
  1362.                 goto badchar;
  1363.             }
  1364.             else if ( !stricmp( keyword, "ALTFONT"))
  1365.             {
  1366.                 goto altfont;
  1367.             }
  1368.             else if ( !stricmp( keyword, "QUIT"))
  1369.             {
  1370.                 goto quit;
  1371.             }
  1372.             else if ( stricmp( keyword, "?"))
  1373.             {
  1374.                 SnapWriteStr( "Bad switch/keyword: ");
  1375.                 SnapWriteStr( keyword);
  1376.                 SnapWriteStr( ".\n");
  1377.             }
  1378. #endif    /* SNAPGFX */
  1379.             usage = 1;
  1380.         }
  1381.     }
  1382.  
  1383.     if ( usage)
  1384.     {
  1385.         SnapWriteStr( "Usage:\n");
  1386. #ifdef SNAPGFX
  1387.         SnapWriteStr( " snap -pNN -tQQ -gQQ -iXX -wXX -Pstr -Astr -cNN -lNN\n");
  1388.         SnapWriteStr( "   -aXXXX -x -X -e -E -uN -r -R -j -J -s -S -bXX -CNN\n");
  1389.         SnapWriteStr( "   -LNN -BNN -Ffont -Q\n");
  1390.         SnapWriteStr( " or\n");
  1391.         SnapWriteStr( " snap PRIORITY/K TEXTQUAL/K GFXQUAL/K INSERTKEY/K CWKEY/K\n");
  1392.         SnapWriteStr( "   PREPEND/K APPEND/K CHARDELAY/K LINEDELAY/K CRAWLPTRN/K\n");
  1393.         SnapWriteStr( "   XEROX/S NOXEROX/S EARLYPATCH/S NOEARLYPATCH/S STARTUNIT/K\n");
  1394.         SnapWriteStr( "   TRUEUNDERSCORE/S FAKEUNDERSCORE/S JOINLONG/S NOJOINLONG/S\n");
  1395.         SnapWriteStr( "   SIMPLEREFRESH/S SMARTREFRESH/S PLANEMASK/K CACHESIZE/K\n");
  1396.         SnapWriteStr( "   LEADING/K BADCHAR/K ALTFONT/K QUIT/S\n");
  1397. #else
  1398.         SnapWriteStr( " snap -pNN -tQQ -iXX -Pstr -Astr -cNN -lNN\n");
  1399.         SnapWriteStr( "   -aXXXX -x -X -e -E -uN -r -R -j -J -bXX -CNN\n");
  1400.         SnapWriteStr( "   -LNN -BNN -Ffont -Q\n");
  1401. #endif    /* SNAPGFX */
  1402.         SnapWriteStr( "\n");
  1403.         SnapWriteStr( "S-Mail: Mikael Karlsson     | E-Mail: micke@slaka.sirius.se\n");
  1404.         SnapWriteStr( "        L÷vsΣttersvΣgen 10  |         micke@slaka.UUCP\n");
  1405.         SnapWriteStr( "        S-585 98  LINK╓PING |         {mxvax|seismo}!sunic!liuida!slaka!micke\n");
  1406.         SnapWriteStr( "        Sweden              | Phone:  +46 ( 0)13 50479\n");
  1407.         goto exitpoint;
  1408.     }
  1409.  
  1410.       skipargs:
  1411.     freopen( "NIL:", "w", stdout);
  1412.  
  1413.     if ( !create)
  1414.     {
  1415.         /* Tell him there are new settings available */
  1416.         Signal( SnapRsrc->Task, SIGBREAKF_CTRL_F);
  1417.         goto exitpoint;
  1418.     }
  1419.  
  1420.     if ( !OpenStuff( ))
  1421.     {
  1422.         goto close;
  1423.     }
  1424.  
  1425.     textqual = SnapRsrc->textqual;
  1426.     gfxqual = SnapRsrc->gfxqual;
  1427.     insertkey = SnapRsrc->insertkey;
  1428.     cwkey = SnapRsrc->cwkey;
  1429.     TrueUnderscore = SnapRsrc->flags & TRUEUNDERSCORE ? 1 : 0;
  1430. #ifdef SNAPGFX
  1431.     SaveName[ 0] = '\0';
  1432. #endif
  1433.  
  1434. #ifdef SNAPREXX
  1435.     rexxsignal = upRexxPort( "SNAP", rcl, NULL, &disp);
  1436. #endif    /* SNAPREXX */
  1437.  
  1438.     /* This is what we're waiting for */
  1439.     WaitSignal = startsignal | insertsignal | initsignal | cancelsignal |
  1440. #ifdef SNAPREXX
  1441.         rexxsignal |
  1442. #endif    /* SNAPREXX */
  1443.         cwsignal | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F;
  1444.  
  1445.     FOREVER
  1446.     {
  1447.         REGISTER LONGBITS sig;
  1448.  
  1449.         sig = Wait( WaitSignal | timersignal
  1450. #ifdef SNAPGFX
  1451.              | ( Sharedport ? ( 1L << Sharedport->mp_SigBit) : 0L)
  1452. #endif    /* SNAPGFX */
  1453.             );
  1454.  
  1455. #ifdef SNAPGFX
  1456.         CheckWindowMsgs( );
  1457. #endif    /* SNAPGFX */
  1458.  
  1459. #ifdef SNAPREXX
  1460.         if ( sig & rexxsignal)
  1461.         {
  1462.             dispRexxPort( );
  1463.         }
  1464. #endif    /* SNAPREXX */
  1465.         if ( sig & SIGBREAKF_CTRL_C)
  1466.         {
  1467.             /* This is my cue. Exit if there are no open windows depending on us */
  1468. #ifdef SNAPGFX
  1469.             if ( Sharedrefs)
  1470.             {
  1471.                 DisplayBeep( NULL);
  1472.             }
  1473.             else
  1474. #endif    /* SNAPGFX */
  1475.             {
  1476.                 goto close;
  1477.             }
  1478.         }
  1479.         if ( sig & SIGBREAKF_CTRL_F)
  1480.         {
  1481.             /* Hey, seems like there are new settings available. */
  1482.             textqual = SnapRsrc->textqual;
  1483.             gfxqual = SnapRsrc->gfxqual;
  1484.             insertkey = SnapRsrc->insertkey;
  1485.             cwkey = SnapRsrc->cwkey;
  1486.             TrueUnderscore = SnapRsrc->flags & TRUEUNDERSCORE ? 1 : 0;
  1487.         }
  1488.         if ( sig & initsignal)
  1489.         {
  1490.             if ( SnapRsrc->flags & ( XEROX | EARLYPATCH))
  1491.             {
  1492.                 SafePatch( );    /* Patch dangerous functions */
  1493.             }
  1494.         }
  1495.         if ( sig & cancelsignal)
  1496.         {
  1497.             SafeRestore( );
  1498.         }
  1499.         if ( sig & startsignal)
  1500.         {        /* The handler wants a word in. */
  1501.             SafePatch( );
  1502. #ifdef SNAPGFX
  1503.             if ( action == snapgfx)
  1504.             {    /* Check user action */
  1505.                 HandleGfx( );    /* Get the picture :-) */
  1506.             }
  1507.             else
  1508. #endif    /* SNAPGFX */
  1509.             if ( action == snaptext && HandleChars( ))
  1510.             {    /* Snap some chars */
  1511.                 if ( SnapRsrc->flags & XEROX)
  1512.                 {
  1513.                     sig |= insertsignal;
  1514.                 }
  1515.             }
  1516.             else
  1517.             {
  1518.                 /* Previous snap wasn't finished when this one started
  1519.                    or this snap failed. */
  1520.                 SetSignal( 0L, movesignal | cancelsignal |
  1521.                      donesignal | clicksignal | ticksignal);
  1522.                 DisplayBeep( NULL);
  1523.                 action = noaction;
  1524.             }
  1525.             if ( !( sig & insertsignal))
  1526.             {
  1527.                 SafeRestore( );    /* Layers unlocked - all safe */
  1528.             }
  1529.         }
  1530.  
  1531.         if ( sig & insertsignal)
  1532.         {
  1533.             LONG i;
  1534.             struct Snap *Snap;
  1535.             ULONG ascii;
  1536.  
  1537.             action = insert;
  1538.             if ( Snap = FetchClip( ))
  1539.             {    /* Get clipboard data */
  1540.                 /* get the current keymap  */
  1541.                 ConIOR->io_Command = CD_ASKDEFAULTKEYMAP;
  1542.                 ConIOR->io_Length = sizeof ( struct KeyMap);
  1543.  
  1544.                 ConIOR->io_Data = ( APTR) & keymap;
  1545.                 ConIOR->io_Flags = 1;    /* no IOQuick   */
  1546.                 DoIO( ( struct IORequest *)ConIOR);
  1547.                 /* Set up an input request */
  1548.                 inputRequestBlock->io_Command = IND_WRITEEVENT;
  1549.                 inputRequestBlock->io_Flags = 0L;
  1550.                 inputRequestBlock->io_Length = ( long)sizeof ( struct InputEvent);
  1551.  
  1552.                 inputRequestBlock->io_Data = ( APTR) & SimEvent;
  1553.                 /* Translate chars in SnapSpace and insert them
  1554.                    into the input stream. */
  1555.                 insertcount = 0;
  1556.                 ascii = 13;    /* Simulate start of new line */
  1557.                 for ( i = 0; Snap->Chars[ i] && ( action == insert); ++i)
  1558.                 {
  1559.                     if ( ascii == 13 && modinsert)
  1560.                     {
  1561.                         int cnt = 0;
  1562.  
  1563.                         while ( ascii = SnapRsrc->Prepend[ cnt++])
  1564.                         {
  1565.                             InsertAscii( ascii);
  1566.                         }
  1567.                     }
  1568.  
  1569.                     ascii = Snap->Chars[ i];
  1570.                     if ( ascii == 10)
  1571.                     {
  1572.                         if ( modinsert)
  1573.                         {
  1574.                             int cnt = 0;
  1575.  
  1576.                             while ( ascii = SnapRsrc->Append[ cnt++])
  1577.                             {
  1578.                                 InsertAscii( ascii);
  1579.                             }
  1580.                         }
  1581.                         ascii = 13;    /* WYSIWYG? Hah! */
  1582.                     }
  1583.                     InsertAscii( ascii);
  1584.                     if ( ascii == 13 && SnapRsrc->linedelay)
  1585.                     {
  1586.                         MyTR.tr_node.io_Command = TR_ADDREQUEST;
  1587.                         MyTR.tr_time.tv_micro = SnapRsrc->linedelay;
  1588.                         MyTR.tr_time.tv_secs = 0;
  1589.                         DoIO( ( struct IORequest *)&MyTR);
  1590.                     }
  1591.                 }
  1592.                 if ( modinsert)
  1593.                 {
  1594.                     int cnt = 0;
  1595.  
  1596.                     while ( ascii = SnapRsrc->Append[ cnt++])
  1597.                     {
  1598.                         InsertAscii( ascii);
  1599.                     }
  1600.                 }
  1601.                 SafeRestore( );    /* "Depatch" */
  1602.                 /* Free memory given to us by FetchClip( ) */
  1603.                 FreeMem( Snap, Snap->Size);
  1604.             }
  1605.             action = noaction;
  1606.             modinsert = 0;
  1607.         }
  1608.  
  1609. #ifdef SNAPGFX
  1610.         if ( sig & cwsignal)
  1611.         {
  1612.             if ( !ControlWindow && !OpenCW( ))
  1613.             {
  1614.                 DisplayBeep( NULL);
  1615.             }
  1616.         }
  1617. #endif    /* SNAPGFX */
  1618.     }
  1619.  
  1620.       close:
  1621. #ifdef SNAPREXX
  1622.     dnRexxPort( );
  1623. #endif    /* SNAPREXX */
  1624.     CloseStuff( );        /* Guess what */
  1625.       exitpoint:
  1626.     CloseLibs( );
  1627. #ifdef AZTEC_C
  1628.     return 0;
  1629. #endif
  1630. }
  1631.